package com.fduss.mazegame.server;

import com.fduss.mazegame.core.maze.Map;
import com.fduss.mazegame.core.unit.End;
import com.fduss.mazegame.core.unit.Hero;
import com.fduss.mazegame.core.unit.Monster;
import com.fduss.mazegame.core.unit.Treasure;

import java.util.Random;

/**
 * Abstract class for all the serverspecs.
 * The serverspecs are used by the client to create a server.
 */
public abstract class ServerSpec {
    protected Map map;
    protected End end;
    protected Hero hero;
    protected Monster[] monsters;
    protected Treasure[] treasures;
    protected int trailCapacity;

    ServerSpec(int rows, int cols, int trailCapacity) {
        if (rows < 1) {
            throw new IllegalArgumentException("rows < 1");
        }
        if (cols < 1) {
            throw new IllegalArgumentException("columns < 1");
        }
        if (trailCapacity < 0) {
            throw new IllegalArgumentException("trailCapacity < 0");
        }
        if (rows % 2 == 0) {
            throw new IllegalArgumentException(
                    "Random maps require an odd number of rows");
        }
        if (cols % 2 == 0) {
            throw new IllegalArgumentException(
                    "Random maps require an odd number of columns");
        }
        this.trailCapacity = trailCapacity;
    }

    ServerSpec(int trailCapacity) {
        if (trailCapacity < 0) {
            throw new IllegalArgumentException("trailCapacity < 0");
        }
        this.trailCapacity = trailCapacity;
    }

    public Map generateMap() {
        return map;
    }

    public End generateEnd() {
        return end;
    }

    public Hero generateHero() {
        return hero;
    }

    public int generateTrailCapacity() {
        return trailCapacity;
    }

    protected Monster[] generateMonsters(int rows, int cols) {
        int num = cols / 10 + rows / 10;
        if (num == 0)
            num = 1; // at least 1 monster
        Monster[] monsters = new Monster[num];
        Random rm = new Random();
        for (int i = 0; i < num; i++) {
            int row = rm.nextInt(rows - 1) + 1;
            int col = rm.nextInt(cols - 1) + 1;
            try {
                monsters[i] = new Monster(map.getPlace(row, col));
            } catch (IllegalArgumentException e) {
                i--; // redo, may cause very long loop.
            }
        }

        return monsters;
    }

    public Monster[] generateMonsters() {
        return this.monsters;
    }

    protected Treasure[] generateTreasure(int rows, int cols) {
        int num = cols / 10 + rows / 10;
        if (num == 0)
            num = 1;
        Treasure[] treasures = new Treasure[num];
        Random rm = new Random();
        for (int i = 0; i < num; i++) {
            int row = rm.nextInt(rows - 1) + 1;
            int col = rm.nextInt(cols - 1) + 1;
            try {
                treasures[i] = new Treasure(map.getPlace(row, col));
            } catch (IllegalArgumentException e) {
                i--; // redo, may cause very long loop.
            }
        }
        return treasures;
    }
}
